
#include "Record.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <iostream.h>
#include <math.h>

Predicate :: ~Predicate () {
	delete [] ops;
}

int Predicate :: Apply (Record &toMe) {

	// loop through all of the clauses in the predicate
	for (int i = 0; i < numOps; i++ ) {
		int res;
		if (ops[i].hisType == Int) {
			res = toMe.GetInt (ops[i].whichAtt) - ops[i].literalVal.GetInt ();
		} else if (ops[i].hisType == Double) {
			res = (int) rint (toMe.GetDouble (ops[i].whichAtt) - ops[i].literalVal.GetDouble ());
		} else {
			char *str1 = ops[i].literalVal.GetString ();
			char *str2 = toMe.GetString (ops[i].whichAtt);
			res = -strcmp (str1, str2);
			delete str1;
			delete str2;
		}
		
		// figure out all of the cases where a predicate fails
		if (ops[i].compOp == '=' && res != 0)
			return 0;

		if (ops[i].compOp == '>' && res <= 0)
			return 0;

		if (ops[i].compOp == '<' && res >= 0)
			return 0;
	}

	return 1;
}

Predicate :: Predicate (Schema &useMe, char *fName) {

	ops = new Op[100];
	FILE *inFile = fopen (fName, "r");
	char attName[100];
	int i = 0;

	while (fscanf (inFile, "%s", attName) != EOF) {
		
		// first, find the attribute name in the schema
		ops[i].whichAtt = useMe.Find (attName);

		// now, get its type
		ops[i].hisType = useMe.FindType (ops[i].whichAtt);

		// read in the comparison operation
		fscanf (inFile, "%s", attName);
		ops[i].compOp = attName[0];

		// and read in the literal
		if (ops[i].hisType == Int) {
			int foo;
			fscanf (inFile, "%d", &foo);
			ops[i].literalVal.LoadInt (foo);	
		} else if (ops[i].hisType == Double) {
			double foo;
			fscanf (inFile, "%lf", &foo);
			ops[i].literalVal.LoadDouble (foo);	
		} else {
			char foo[200];
			fscanf (inFile, "%s", foo);
			foo [strlen (foo) - 1] = 0;
			ops[i].literalVal.LoadString (foo + 1);	
		}
		
		i++;
	}

	numOps = i;
	
}
